﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CNWebBase
{
    internal delegate bool ValidateRoleDelegate(long UserID);
    internal static class RoleValidator
    {
        internal static object StaticLock = new object();
        //TODO: need to check if delegate cache really necessary here, otherwise code will be simplified a lot.
        internal static Dictionary<string, ValidateRoleDelegate> RoleValidateDelegates;
        protected static NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
        static RoleValidator()
        {
            Cache.CacheInitialized += new Cache.CacheInitializedEventHandler(Cache_CacheInitialized);
        }

        static void Cache_CacheInitialized()
        {
            lock (StaticLock)
            {
                try
                {
                    RoleValidateDelegates = Cache.GetRoleValidateMethodNames().ToDictionary(mn_key => mn_key, mn_value => Delegate.CreateDelegate(typeof(ValidateRoleDelegate), typeof(RoleValidator), mn_value) as ValidateRoleDelegate);
                }
                catch (Exception ex)
                {
                    Logger.FatalException("Can not initialize role validate methods, need to check method name specification in roles stored in database, see if any of them can not match the code.", ex);
                    throw;
                }
            }
        }
        internal static bool ValidateRole(long UserID, Role CadidateRole)
        {
            return ValidateRole(UserID, CadidateRole.ValidateMethodName);
        }
        internal static bool ValidateRole(long UserID, string ValidateMethodName)
        {
            ValidateRoleDelegate dValidator;
            if (RoleValidateDelegates.TryGetValue(ValidateMethodName, out dValidator))
            {
                dValidator = dValidator.Clone() as ValidateRoleDelegate;
                //NOTE: all validator method should be thread-safe.
                return dValidator(UserID);
            }
            else
            {
                Logger.Error("Can not find specified method for validating role {0}, this may result in outdated role or validate method cache, try refresh system cache. role validate result will be kept false until that resolved.");
                return false;
            }
        }
    }
}
